package com.umeox.watch.moto.launcher.keyboard;

import android.app.Dialog;
import android.content.Context;
import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.KeyboardView;
import android.os.Build;
import android.os.IBinder;
import android.text.TextUtils;
import android.text.method.MetaKeyKeyListener;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;

import com.umeox.moto.common.log.Logger;
import com.umeox.watch.moto.launcher.R;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Rambo 2024/3/12/0012
 * Describe:
 */
public final class SoftKeyboardService extends InputMethodService implements KeyboardView.OnKeyboardActionListener {

    private InputMethodManager mInputMethodManager;

    private CompletionInfo[] completionInfo;

    private final StringBuilder stringBuilder = new StringBuilder();

    private InputMethodView mInputMethodView;

    private boolean isFullScreenMode;

    private boolean f6315i;

    private long mateState;

    private String wordSeparator;

    private int mMaxWidth;

    @Override
    public void onCreate() {
        super.onCreate();
        Logger.e("==================SoftKeyboardService onCreate=============================");
        mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
        for (InputMethodInfo inputMethodInfo : mInputMethodManager.getInputMethodList()) {
            if (TextUtils.equals(inputMethodInfo.getPackageName(), getPackageName())) {
                mInputMethodManager.setInputMethod(getTokenBinder(), inputMethodInfo.getId());
            }
        }

        wordSeparator = getResources().getString(R.string.word_separators);
    }

    @Override
    public View onCreateInputView() {
        mInputMethodView = (InputMethodView) getLayoutInflater().inflate(R.layout.view_input, (ViewGroup) null);
        mInputMethodView.setOnKeyActionListener(this);
        return mInputMethodView;
    }

    private IBinder getTokenBinder() {
        Dialog window = getWindow();
        if (window == null || window.getWindow() == null) {
            return null;
        }
        return window.getWindow().getAttributes().token;
    }


    @Override
    public void onPress(int primaryCode) {

    }

    @Override
    public void onRelease(int primaryCode) {

    }

    @Override
    public void onKey(int primaryCode, int[] keyCodes) {
        if (primaryCode == -5) { //删除键
            delete();
        } else if (primaryCode == -3) {
            hideSelf();
        } else if (primaryCode == -1) {
            setShifted();
        } else {
            switch (primaryCode) {
                case -102:
                case -101:
                case -100:
                    InputMethodView inputMethodView = this.mInputMethodView;
                    inputMethodView.setKeyboardType(primaryCode);
                    return;
                default:
                    Log.i("myFirst_IME", "isWordSeparator:" + primaryCode);
                    handPrimaryCode(primaryCode, keyCodes);
            }
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        InputConnection currentInputConnection;
        if (keyCode == 4) {
            event.getRepeatCount();
        } else if (keyCode == 66) {
            return false;
        } else {
            if (keyCode != 67) {
                if (keyCode == 62 && (event.getMetaState() & 2) != 0 && (currentInputConnection = getCurrentInputConnection()) != null) {
                    currentInputConnection.clearMetaKeyStates(2);
                    senKeyEvent(29);
                    senKeyEvent(42);
                    senKeyEvent(32);
                    senKeyEvent(46);
                    senKeyEvent(43);
                    senKeyEvent(37);
                    senKeyEvent(32);
                    return true;
                } else if (this.f6315i && handKeyDown(keyCode, event)) {
                    return true;
                }
            } else if (this.stringBuilder.length() > 0) {
                onKey(-5, null);
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (this.f6315i) {
            this.mateState = MetaKeyKeyListener.handleKeyUp(this.mateState, keyCode, event);
        }
        return super.onKeyUp(keyCode, event);
    }

    @Override
    public void onText(CharSequence text) {
        InputConnection currentInputConnection = getCurrentInputConnection();
        if (currentInputConnection == null) {
            return;
        }
        currentInputConnection.beginBatchEdit();
        if (this.stringBuilder.length() > 0) {
            commitText(currentInputConnection);
        }
        currentInputConnection.commitText(text, 0);
        currentInputConnection.endBatchEdit();
    }

    @Override
    public void onStartInput(EditorInfo attribute, boolean restarting) {
        super.onStartInput(attribute, restarting);
        this.stringBuilder.setLength(0);
        setCandidatesViewShown();
        if (!restarting) {
            this.mateState = 0L;
        }
        this.f6315i = false;
        this.isFullScreenMode = false;
        this.completionInfo = null;
        int i10 = attribute.inputType;
        int i11 = i10 & 15;
        if (i11 == 1) {
            int i12 = i10 & 4080;
            if (i12 == 128 || i12 == 144) {
                this.f6315i = false;
            }
            if (i12 == 16 || i12 == 32 || i12 == 176) {
                this.f6315i = false;
            }
            if ((i10 & 65536) != 0) {
                this.f6315i = false;
                this.isFullScreenMode = isFullscreenMode();
            }
        } else if (i11 == 2 || i11 == 3 || i11 == 4) {
            return;
        }
    }

    @Override
    public void onUpdateSelection(int oldSelStart, int oldSelEnd, int newSelStart, int newSelEnd, int candidatesStart, int candidatesEnd) {
        super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, candidatesStart, candidatesEnd);
        if (this.stringBuilder.length() > 0) {
            if (newSelStart == candidatesEnd && newSelEnd == candidatesEnd) {
                return;
            }
            this.stringBuilder.setLength(0);
            setCandidatesViewShown();
            InputConnection currentInputConnection = getCurrentInputConnection();
            if (currentInputConnection != null) {
                currentInputConnection.finishComposingText();
            }
        }
    }

    @Override
    public void onFinishInput() {
        super.onFinishInput();
        stringBuilder.setLength(0);
        setCandidatesViewShown();
        setCandidatesViewShown(false);
    }

    @Override
    public void onDisplayCompletions(CompletionInfo[] completions) {
        if (this.isFullScreenMode) {
            this.completionInfo = completions;
            if (completions == null) {
                setCandidatesViewShown(null, false, false);
                return;
            }
            ArrayList<String> arrayList = new ArrayList<>();
            for (CompletionInfo completionInfo : completionInfo) {
                if (completionInfo != null) {
                    arrayList.add(completionInfo.getText().toString());
                }
            }
            setCandidatesViewShown(arrayList, true, true);
        }
    }

    @Override
    public void onInitializeInterface() {
        createDisplayContext();
        int maxWidth = getMaxWidth();
        if (maxWidth == mMaxWidth) {
            return;
        }
        mMaxWidth = maxWidth;
    }

    public  Context createDisplayContext() {
        if (Build.VERSION.SDK_INT >= 32) {
            return this;
        }
        WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        Context displayContext = createDisplayContext(windowManager.getDefaultDisplay());
        return displayContext;
    }

    @Override
    public void swipeLeft() {
        delete();
    }

    @Override
    public void swipeRight() {
        if(isFullScreenMode){
            l(0);
        }
    }

    public void l(int i10) {
        CompletionInfo[] completionInfoArr;
        if (this.isFullScreenMode && (completionInfoArr = this.completionInfo) != null && i10 >= 0) {
            if (i10 < completionInfoArr.length) {
                getCurrentInputConnection().commitCompletion(completionInfo[i10]);
                return;
            }
        }
        if (this.stringBuilder.length() > 0) {
            InputConnection currentInputConnection = getCurrentInputConnection();
            commitText(currentInputConnection);
        }
    }

    @Override
    public void swipeDown() {
        hideSelf();
    }

    @Override
    public void swipeUp() {

    }


    private void commitText(InputConnection inputConnection) {
        if (stringBuilder.length() > 0) {
            inputConnection.commitText(stringBuilder, stringBuilder.length());
            stringBuilder.setLength(0);
            setCandidatesViewShown();
        }
    }

    private void setCandidatesViewShown() {
        ArrayList<String> arrayList;
        boolean z10;
        if (isFullScreenMode) {
            return;
        }
        if (stringBuilder.length() > 0) {
            arrayList = new ArrayList<>();
            arrayList.add(stringBuilder.toString());
            z10 = true;
        } else {
            arrayList = null;
            z10 = false;
        }
        setCandidatesViewShown(arrayList, z10, z10);
    }

    public void setCandidatesViewShown(List<String> list, boolean z10, boolean z11) {
        if ((list == null || list.isEmpty()) && !isExtractViewShown()) {
            return;
        }
        setCandidatesViewShown(true);
    }

    private void delete() {
        int length = this.stringBuilder.length();
        if (length > 1) {
            this.stringBuilder.delete(length - 1, length);
            getCurrentInputConnection().setComposingText(this.stringBuilder, 1);
        } else if (length <= 0) {
            senKeyEvent(67);
        } else {
            this.stringBuilder.setLength(0);
            getCurrentInputConnection().commitText("", 0);
        }
        setCandidatesViewShown();
    }

    private void senKeyEvent(int keyCode) {
        getCurrentInputConnection().sendKeyEvent(new KeyEvent(0, keyCode));
        getCurrentInputConnection().sendKeyEvent(new KeyEvent(1, keyCode));
    }

    private void hideSelf() {
        InputConnection currentInputConnection = getCurrentInputConnection();
        commitText(currentInputConnection);
        requestHideSelf(0);
    }

    private void setShifted() {
        if (mInputMethodView == null) {
            return;
        }
        mInputMethodView.setShifted(!mInputMethodView.getShifted());
    }

    private void handPrimaryCode(int primaryCode, int[] keyCodes) {
        Log.i("Umeox_IME", "isInputViewShown: " + primaryCode);
        if (isInputViewShown()) {
            if (mInputMethodView.getShifted()) {
                primaryCode = Character.toUpperCase(primaryCode);
            }
        }
        if (!isLetter(primaryCode) || !this.f6315i) {
            getCurrentInputConnection().commitText(String.valueOf((char) primaryCode), 1);
            return;
        }
        this.stringBuilder.append((char) primaryCode);
        getCurrentInputConnection().setComposingText(this.stringBuilder, 1);
        setCandidatesViewShown();
    }

    private boolean isLetter(int primaryCode) {
        return Character.isLetter(primaryCode);
    }


    private boolean handKeyDown(int keyCode, KeyEvent keyEvent) {
        long handleKeyDown = MetaKeyKeyListener.handleKeyDown(this.mateState, keyCode, keyEvent);
        this.mateState = handleKeyDown;
        int unicodeChar = keyEvent.getUnicodeChar(MetaKeyKeyListener.getMetaState(handleKeyDown));
        this.mateState = MetaKeyKeyListener.adjustMetaAfterKeypress(this.mateState);
        InputConnection currentInputConnection = getCurrentInputConnection();
        if (unicodeChar == 0 || currentInputConnection == null) {
            return false;
        }
        if ((Integer.MIN_VALUE & unicodeChar) != 0) {
            unicodeChar &= Integer.MAX_VALUE;
        }
        if (this.stringBuilder.length() > 0) {
            int deadChar = KeyEvent.getDeadChar(stringBuilder.charAt(stringBuilder.length() - 1), unicodeChar);
            if (deadChar != 0) {
                stringBuilder.setLength(stringBuilder.length() - 1);
                unicodeChar = deadChar;
            }
        }
        onKey(unicodeChar, null);
        return true;
    }
}
